/**
 * 
 */
package br.odb.utils;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;

import br.odb.libscene.Sector;
import br.odb.utils.math.Vec2;
import br.odb.utils.math.Vec3;
/**
 * @author monty
 *
 */
public class Utils {
	
	
//	 public static String readLine( InputStream reader) throws IOException {
	//	        StringBuffer line = new StringBuffer();
	//	        int c = reader.read();
	//
	//	        while (c != -1 && c != '\n') {
	//	            line.append((char)c);
	//	            c = reader.read();
	//	        }
	//
	//	        if (line.length() == 0) {
	//	            return null;
	//	        }
	//
	//	        return line.toString();
	//	    }

	/**
	 * @author monty
	 *
	 */


	private static int clamp(int angle) {
		int quadrant = angle;
		while (quadrant < 0) {
			quadrant += 16;
		}
		quadrant = (quadrant) % 16;
		return quadrant;
	}
	
	public static int getLeft( int currentDirection ) {
		int toReturn = currentDirection;

		
		--toReturn;

		while ( toReturn < 0 )
			toReturn += 4;
		
		return toReturn;
	}
	
	public static int getRight( int dir ) {
		int toReturn = dir;

		if ( toReturn < Sector.FACE_FLOOR )
			++toReturn;
		
		return toReturn;
	}
	
	public static Vec2 getTranslationForOctant( int octant ) {
		return translations[ clamp( octant) ];
	}
	
	private static Vec2[] translations;
	

	public static boolean eqFloat( float f1, float f2 ) {
		int int1 = (int) (f1 * 1000);
		int int2 = (int) (f2 * 1000);
		return int1 == int2;
	} 
	
	public static boolean eqFloat( float f1, float f2, int point ) {
		int int1 = (int) (f1 * point);
		int int2 = (int) (f2 * point);
		return int1 == int2;
	}
	

	static {
		translations = new Vec2[17];
//		translations[0] = new Vec2(0, 1);
//		translations[1] = new Vec2(0.38f, 0.93f);
//		translations[2] = new Vec2(0.7f, 0.7f);
//		translations[3] = new Vec2(0.7f, 0.38f);
//		translations[4] = new Vec2(1, 0);
//		translations[5] = new Vec2(0.93f, -0.38f);
//		translations[6] = new Vec2(0.7f, -0.7f);
//		translations[7] = new Vec2(0.38f, -0.93f);
//		translations[8] = new Vec2(0, -1);
//		translations[9] = new Vec2(-0.38f, -0.93f);
//		translations[10] = new Vec2(-0.7f, -0.7f);
//		translations[11] = new Vec2(-0.93f, -0.38f);
//		translations[12] = new Vec2(-1, 0);
//		translations[13] = new Vec2(-0.93f, 0.38f);
//		translations[14] = new Vec2(-0.7f, 0.7f);
//		translations[15] = new Vec2(-0.38f, 0.93f);
//		translations[16] = new Vec2(0, 1);
		
		translations[ 0] = new Vec2( ( float ) Math.sin( 0.000f * Math.PI )/4.0f, ( float ) Math.cos( 0.000f * Math.PI )/4.0f ); //0
		translations[ 1] = new Vec2( ( float ) Math.sin( 0.125f * Math.PI )/4.0f, ( float ) Math.cos( 0.125f * Math.PI )/4.0f );
		translations[ 2] = new Vec2( ( float ) Math.sin( 0.250f * Math.PI )/4.0f, ( float ) Math.cos( 0.250f * Math.PI )/4.0f );
		translations[ 3] = new Vec2( ( float ) Math.sin( 0.375f * Math.PI )/4.0f, ( float ) Math.cos( 0.375f * Math.PI )/4.0f );		
		translations[ 4] = new Vec2( ( float ) Math.sin( 0.500f * Math.PI )/4.0f, ( float ) Math.cos( 0.500f * Math.PI )/4.0f );
		translations[ 5] = new Vec2( ( float ) Math.sin( 0.625f * Math.PI )/4.0f, ( float ) Math.cos( 0.625f * Math.PI )/4.0f );
		translations[ 6] = new Vec2( ( float ) Math.sin( 0.750f * Math.PI )/4.0f, ( float ) Math.cos( 0.750f * Math.PI )/4.0f );
		translations[ 7] = new Vec2( ( float ) Math.sin( 0.875f * Math.PI )/4.0f, ( float ) Math.cos( 0.875f * Math.PI )/4.0f );		
		translations[ 8] = new Vec2( ( float ) Math.sin( 1.000f * Math.PI )/4.0f, ( float ) Math.cos( 1.000f * Math.PI )/4.0f ); //180		
		
		
		translations[ 9] = new Vec2( ( float ) Math.sin( 1.125f * Math.PI )/4.0f, ( float ) Math.cos( 1.125f * Math.PI )/4.0f );
		translations[10] = new Vec2( ( float ) Math.sin( 1.250f * Math.PI )/4.0f, ( float ) Math.cos( 1.250f * Math.PI )/4.0f );
		translations[11] = new Vec2( ( float ) Math.sin( 1.375f * Math.PI )/4.0f, ( float ) Math.cos( 1.375f * Math.PI )/4.0f );
		translations[12] = new Vec2( ( float ) Math.sin( 1.500f * Math.PI )/4.0f, ( float ) Math.cos( 1.500f * Math.PI )/4.0f );
		translations[13] = new Vec2( ( float ) Math.sin( 1.625f * Math.PI )/4.0f, ( float ) Math.cos( 1.625f * Math.PI )/4.0f );
		translations[14] = new Vec2( ( float ) Math.sin( 1.750f * Math.PI )/4.0f, ( float ) Math.cos( 1.750f * Math.PI )/4.0f );
		translations[15] = new Vec2( ( float ) Math.sin( 1.875f * Math.PI )/4.0f, ( float ) Math.cos( 1.875f * Math.PI )/4.0f );
		translations[16] = new Vec2( ( float ) Math.sin( 2.000f * Math.PI )/4.0f, ( float ) Math.cos( 2.000f * Math.PI )/4.0f );
	}


	public static int clamp( int n, int min, int max ) {

		if ( min > max )
			return clamp( n, max, min );		
		
		if ( n < min )
			n = min;

		if ( n > max )
			n = max;		
		
		return n;
	}
	
	public static float clamp( float n, float min, float max ) {

		if ( min > max )
			return clamp( n, max, min );		
		
		if ( n < min )
			n = min;

		if ( n > max )
			n = max;		
		
		return n;
	}


	public static int getOppositeDirection(int d) {

		switch( d ) {
		
			case 0:
				return 2;
			case 1:
				return 3;
			case 2:
				return 0;
			case 3:
				return 1;
			case 4:
				return 5;
			case 5:
				return 4;
		}
		
		return 0;
	}

	public static float snap(float value) {
		
		return (int)value;
	}

	public static int pow2For(int x) {

		   --x;
		    x |= x >> 1;
		    x |= x >> 2;
		    x |= x >> 4;
		    x |= x >> 8;
		    x |= x >> 16;
		    return ++x;
		}
}
